/**
 * Elite trcclink CTI Client
 * Created by Jeff on 2018/05/28
 */
//动态引入JS文件
var version1 = new Date().getTime();
//TINET_TOOLBAR_URL定义工具条地址, 变量名称不能改
var CCIC2_TOOLBAR_URL = "";	//"http://agent.clink.cn";
//document.write("<script src='"+CCIC2_TOOLBAR_URL+"/jws/sourceCode/ccic2Toolbar.js?version="+version1+"' charset='UTF-8'><\/script>");
//document.write("<script src='"+$E.softphoneBasePath + "/softphone/trcclinkconfig.js' type='text/javascript'><\/script>");

var cbLogin;
var cbLogout;
var cbChangeBindTel;
var cbPause;
var cbUnpause;
var cbStatus;
var cbQueueStatus;
var cbThisStatus;
var cbQueue;
var cbKickout;
var cbBackendLogout;
var cbBreakLine;
var cbUnanswer;
var cbAgenda;
var cbRefuse;
var cbPreviewOutCall;
var cbPreviewOutCallCancel;
var cbUnLink;
var cbHold;
var cbUnhold;
var cbConsultCancel;
var cbUnconsult;
var cbConsultTransfer;
var cbConsultThreeway;
var cbTransfer;
var cbInteract;


define([$E.softphoneBasePath + "/softphone/softphone.constants" + $E.jsv], function($CTI_CONST){
	var MSGTYPE = $CTI_CONST.CTI_MSG;
	
	var ccic2loaded = 0;
	var delaylogin = false;
	var _l = {};
	
	//debugger;
	/*
	var js1 = CCIC2_TOOLBAR_URL+"/jws/sourceCode/ccic2Toolbar.js?version="+version1;
	require([js1], function(){
		console.log("[_trcclink] js loaded: " + js1); 
	})
    */
	//document.write("<script src='"+CCIC2_TOOLBAR_URL+"/jws/sourceCode/ccic2Toolbar.js?version="+version1+"' charset='UTF-8'><\/script>");

	function addJsonStringValue(jsonobj, name, value)
	{
		jsonobj[name.toLowerCase()] = {type: 3, value: value};
	}

	function addJsonIntValue(jsonobj, name, value)
	{
		jsonobj[name.toLowerCase()] = {type: 1, value: value};
	}

	function addJsonDatasValue(jsonobj, name, value)
	{
		jsonobj[name.toLowerCase()] = {type: 5, value: value};
	}

	function getJsonString(jsonobj, name)
	{
		if(jsonobj.hasOwnProperty(name)){
			return jsonobj[name];
		}
		return "";
	}

    function isJson(content){
    	try {
            var jsonStr= JSON.parse(content);
            return true;
    	} catch (e) {
            return false;
    	}
    }

	function isArray(object) {
	    return  object && typeof object==='object' &&    
	            typeof object.length==='number' &&  
	            typeof object.splice==='function' &&    
	             //判断length属性是否是可枚举的 对于数组 将得到false  
	            !(object.propertyIsEnumerable('length'));
	}
	
    function getdatabykey(datas, key) {
    	var d = datas
    	try {
    		if (typeof(d) == 'string') {
    			d = JSON.parse(d);
    		}
    		if (d) {
				for (var vkey in d) {
    				if (vkey.toLowerCase() == key.toLowerCase()) {
    					if (typeof(d)=='object') {
    						if (d.hasOwnProperty('value')) {
    							return d[vkey].value;
    						} else {
    							return d[vkey];
    						}
    					} else {
    						return d[vkey];
    					}
    				}
    			}		    			
    		}
	    } catch (err) {
    		
    	}
    }

    function tosimpleuserdata(datas) {
    	//将随路数据同一成JSON对象。特别地，如果随路数据中包含raw_data或uu_data，则只保留这部分内容
    	try {
    		if (typeof(datas) == 'string') {
    			datas = JSON.parse(datas);
    		}
    		var uui = getdatabykey(datas, 'uu_data');
    		if (uui) {
    			return {'uui' : uui};
    		} else {
    			var uui = getdatabykey(datas, 'raw_data');
    		}
			if (uui) {
				try {
					uui = JSON.parse(uui);
				} catch (err) {
					
				}
				return uui;
			} else {
				//return datas;
				var uui = '';
				var v;
				for (var p in datas) {
					if (datas[p].hasOwnProperty('value')) {
						v = tosimpledata(datas[p].value);
					} else {
						v = datas[p];
					}
					uui = uui + '|' + p + '=' + v;
				}
				uui = uui.substring(1);
				return {'uui': uui};
			}
    	} catch (err) {
    		return {'uui' : datas};
    	}
    }
    
    function tosimpledata(data) {
    	try {
    		if (typeof(data) == 'object') {
        		var jdata = {};
        		for (var p in data) {
        			if (data[p].hasOwnProperty('value')) {
            			jdata[p] = tosimpledata(data[p].value);
        			} else {
        				jdata[p] = data[p];
        			}
        		}
        		return jdata;
    		} else {
    			return data;
    		}
    	} catch (err) {
    		return data;
    	}
    }

    function commonreplace(template, args) {
        if (arguments.length > 1 && typeof arguments[0] === "string") {
            var result = arguments[0];
            if (arguments.length == 2 && typeof arguments[1] === "object") {
                var obj = arguments[1];
                for (var key in obj) {
                    if (obj[key] != undefined) {
                        var reg = new RegExp("({" + key + "})", "g");
                        result = result.replace(reg, obj[key]);
                    }
                }
            } else {
                for (var i = 1, len = arguments.length; i < len; i++) {
                    if (arguments[i] != undefined) {
                        // 这个在索引大于9时会有问题
                        // var reg = new RegExp("({[" + (i - 1) + "]})", "g");
                        var reg = new RegExp("({)" + (i - 1) + "(})", "g");
                        result = result.replace(reg, arguments[i]);
                    }
                }
            }
            return result;
        } else {
            return arguments[0];
        }
    }
    
    var ELITETRCCLINK = {
		createNew : function(){
			var conn1="conn-1";
			var conn2="conn-2";

			var softphone = {};	
			
			softphone.logined = false;
			softphone.logoutbeforelogin  = 0;
			softphone.keepalivetimer = 0;
			softphone.invokeid = 0;
			softphone.rqqueue = {};
			softphone.currentdest = "";
			softphone.dn = "";
			softphone.channelid = 1;
			softphone.agentid = "";
			softphone.agentpassword = "";
			softphone.agentgroup = "";
			softphone.skillId = "";
			softphone.activeid = "";
			softphone.heldid = "";


			var trconfig = $E.softphoneBasePath + "/softphone/trcclinkconfig.js";
			require([trconfig], function(){
				CCIC2_TOOLBAR_URL = TRCCLinkConfig.CCIC2_TOOLBAR_URL;
				console.log("[_trcclink] js loaded: " + trconfig + ",CCIC2_TOOLBAR_URL=" + CCIC2_TOOLBAR_URL); 

				window.readyLoad = function(){
					console.log('ccic2Toolbar loaded done');
					ccic2loaded = 3;
					if (delaylogin) {
						softphone.logmsg('to do delay login')
						delaylogin = false;
						softphone.login(_l.agentid, _l.dn, _l.agentpassword, _l.agentgroup, _l.workmode, _l.acdagent);
					}
				}
				
				/*
				var js1 = CCIC2_TOOLBAR_URL+"/jws/sourceCode/ccic2Toolbar.js?version="+version1;
				console.log('to getScript: ' + js1);
				ccic2loaded = 1;
				$.getScript([js1], function(){
					console.log('getScript done: ' + js1);
					ccic2loaded = 2;

				})
				*/
			})
			
			var Error = function (error, args) {
		        return this.init(error, args);
		    };
		    Error.UNKNOW_ERROR = {
	            code: 80000,
	            name: "UNKNOW_ERROR",
	            message: "未知错误"
	        };
		    Error.INVOKE_TIMEOUT = {
		        code: 80100,
		        name: "INVOKE_TIMEOUT",
		        message: "请求超时 - {method}"
		    };
		    Error.INVOKE_ERROR = {
		    	code: 80101,
		    	name: "INVOKE_ERROR",
		    	message: "请求出错  - {method}: {errmsg}"
		    }
		    Error.NO_DEVICE_INFO = {
		        code: 80110,
		        name: "NO_DEVICE_INFO",
		        message: "未获取到分机信息"
		    };
		    Error.INVALID_DEVICE_ID = {
		        code: 80111,
		        name: "INVALID_DEVICE_ID",
		        message: "无效的分机号：{deviceId}"
		    };
		    Error.EXIST_DEVICE_LOGIN = {
		        code: 80112,
		        name: "EXIST_DEVICE_LOGIN",
		        message: "分机已登录，登录工号：{agentId}",
		    };
		    Error.RESOURCE_BUSY = {
		        code: 80113,
		        name: "RESOURCE_BUSY",
		        message: "分机正在通话"
		    };

		    Error.INVALID_AGENT_ID = {
		        code: 80121,
		        name: "INVALID_AGENT_ID",
		        message: "无效的工号：{agentId}"
		    };
		    Error.INVALID_PASSWORD = {
	            code: 80122,
	            name: "INVALID_PASSWORD",
	            message: "无效的密码"
	        };
		    Error.EXIST_AGENT_LOGIN = {
		        code: 80123,
		        name: "EXIST_AGENT_LOGIN",
		        message: "工号已登录，登录分机：{deviceId}"
		    };
		    Error.prototype = {
	            constructor: Error,
	            init: function (error, args) {
	                var newError = null;
	                if (typeof error === "object") {
	                    if (typeof args != undefined) {
	                        newError = Object.create(error);
	                        for (var name in newError) {
	                            newError[name] = commonreplace(newError[name], args);
	                        }
	                    } else {
	                        newError = error;
	                    }
	                } else if (typeof error === "string") {
	                    newError = {
	                        code: 80999,
	                        name: "Error",
	                        message: error
	                    };
	                }
	                return newError;
	            }
	        };

			
			softphone.logmsg = function(msg, jsonobj)
			{
				if (jsonobj) {
			    	console.log("[_trcclink]" + msg + ": " + JSON.stringify(jsonobj));
				} else {
			    	console.log("[_trcclink]" + msg);
				}
			}
			
			softphone.InternalOnError = function(errMessage, errorCode, errorName)
			{
				var ret = {};
				ret.event = {type: 1, value: $CTI_CONST.CTI_MSG.EVT_ERROR};
	        	ret.dn = {type: 3, value: this.dn};
	        	//ret.channelid = this.channelid;
	        	if (!errorCode) {
	        		errorCode = 80001
	        	}
	        	ret.errorcode = {type: 3, value: errorCode};
	        	ret.errordesc = {type: 3, value: errMessage};
	        	if (errorName) {
	        		ret.errorname = {type: 3, value: errorName};
	        	}
	        	softphone.OnCTIEvent(JSON.stringify(ret));
			}
			
			softphone.InternalOnErrorCode = function(errorCode, errorMsg)
			{
				var ret = {};
				ret.event = {type: 1, value: $CTI_CONST.CTI_MSG.EVT_ERROR};
	        	ret.dn = {type: 3, value: this.dn};
	        	//ret.channelid = this.channelid;
	        	if (!errorCode) {
	        		errorCode = 80001
	        	}
	        	ret.errorcode = {type: 3, value: errorCode};
	        	ret.errordesc = {type: 3, value: errorMsg};
	        	softphone.OnCTIEvent(JSON.stringify(ret));
			}
			
			softphone.LeftFill = function(s, len, fillchar)
			{
				var ret = "";
				for (var i = s.length; i < len; i++)
				{
					ret = ret + fillchar;;
			    }
				return ret + s;
			}
			
			softphone.RightFill = function(s,len,fillchar)
			{
				var ret = "";
				for (var i = s.length; i < len; i++)
				{
					ret=ret + fillchar;;
				}
				return s + ret;
			}

			softphone.keepalive = function()
			{
				
			}

			//action
			softphone.connectserver = function(serverendpoint, onOpen, onClose, onMessage, onError, onSendMessage){
				//debugger;
				softphone.OnSendMessage = onSendMessage;
				softphone.OnMessage = onMessage;
				softphone.OnError = onError;
				if (ccic2loaded >= 2) {
					var evt = {};
					addJsonIntValue(evt,"event",MSGTYPE.EVT_LINKCONNCTED);
					addJsonStringValue(evt,"eventdesc","EVT_LINKCONNECTED");
					softphone.OnCTIEvent(evt);
				}
				
				if (ccic2loaded == 0) {
				//	ccic2loaded = 1;
					var ccic2js = TRCCLinkConfig.ccic2js;
					if (!ccic2js) {
						ccic2js = "/jws/sourceCode/ccic2Toolbar.js";
					} else {
						//if (ccic2js.substr(0,1) != '/') {
						//	ccic2js = '/' + ccic2js;
						//}
					}
					var js1 = CCIC2_TOOLBAR_URL + ccic2js + "?version="+version1;
					console.log('to require: ' + js1);
					ccic2loaded = 1;
					require([js1], function(){
						console.log('required: ' + js1);
						ccic2loaded = 2;
						var evt = {};
						addJsonIntValue(evt,"event",MSGTYPE.EVT_LINKCONNCTED);
						addJsonStringValue(evt,"eventdesc","EVT_LINKCONNECTED");
						softphone.OnCTIEvent(evt);
					})
					/*
					softphone.logmsg('document write: ' + js1);
					document.write("<script src='"+js1+"' charset='UTF-8'><\/script>");
					softphone.logmsg('document writed: ' + js1);
					ccic2loaded = 2;
					var evt = {};
					addJsonIntValue(evt,"event",MSGTYPE.EVT_LINKCONNCTED);
					addJsonStringValue(evt,"eventdesc","EVT_LINKCONNECTED");
					softphone.OnCTIEvent(evt);
					*/
				}
				
			};

			softphone.registerdn = function(dn)
		    {
		    	this.dn = dn;
		    	this.channelid = 1;
		    	var ret = {};
				addJsonIntValue(ret,"dn", this.dn);
		    	addJsonIntValue(ret,"channelid", this.channelid);
		    	addJsonIntValue(ret,"event",MSGTYPE.EVT_REGISTERED);
		    	addJsonStringValue(ret,"eventdesc","EVT_REGISTERED");
		    	this.OnCTIEvent(ret);
		    };

		    softphone.login = function(agentid,dn,agentpassword,agentgroup,workmode,acdagent)
		    {
				cbLogin = softphone.cbLogin;
				cbLogout = softphone.cbLogout;
				//cbChangeBindTel = softphone.cbChangeBindTel;
				cbPause = softphone.cbPause;
				cbUnpause = softphone.cbUnpause;
				//cbStatus = softphone.cbStatus;
				//cbQueueStatus;
				cbThisStatus = softphone.cbThisStatus;
				//cbQueue;
				//cbKickout;
				//cbBackendLogout;
				//cbBreakLine;
				//cbUnanswer;
				//cbAgenda;
				//cbRefuse;
				cbPreviewOutCall = softphone.cbPreviewOutCall;
				cbPreviewOutCallCancel = softphone.cbPreviewOutCallCancel;
				//cbUnLink;
				cbHold = softphone.cbHold;
				cbUnhold = softphone.cbUnhold;
				cbConsultCancel = softphone.cbConsultCancel;
				cbUnconsult = softphone.cbUnconsult;
				cbConsultTransfer = softphone.cbConsultTransfer;
				//cbConsultThreeway;
				cbTransfer = softphone.cbTransfer;
				//cbInteract;

				try{
		    		if (ccic2loaded < 3) {
		    			//var err = new Error(8000, 'ccic2Toolbar.js未加载完成。');
		    			//softphone.InternalOnError('ccic2Toolbar.js未加载完成。', 80001, 'UNKNOW_ERROR');
		    			softphone.logmsg('login delayed for ccic2loaded = ' + ccic2loaded);
		    			delaylogin = true;
		    			_l = {
		    					agentid: agentid,
		    					dn: dn,
		    					agentpassword: agentpassword,
		    					agentgroup: agentgroup,
		    					workmode: workmode,
		    					acdagent: acdagent
		    			}
		    			return false;
		    		}
		    		
					var params = {};
					params.hotLine =TRCCLinkConfig.hotline;  
					params.cno =  agentid; 
					params.pwd =  agentpassword; 
					params.bindTel =  this.dn;
					params.bindType = "1";
					if(TRCCLinkConfig.softphonerangeregex.test(this.dn)){
						params.bindType = "3";
					}else if(TRCCLinkConfig.extensionrangeregex.test(this.dn)){
						params.bindType = "2";
					}else if (TRCCLinkConfig.remotephonerangeregex && TRCCLinkConfig.remotephonerangeregex.test(this.dn)) {
						params.bindType = "4";
					}
					this.logmsg("bindtype is " + params.bindType);
					params.initStatus =  "pause"; 
					if(params.bindType == "3"){
						//not supported yet
						//params.sipIp = sipip;
						//params.sipPwd = sipPwd;
					}
					//debugger;
					
					softphone.callexecuteAction('doLogin',  params);
					return true;
				}catch(e){
					this.logmsg("agentlogin error:" + e.message);
	    			var err = new Error(Error.INVOKE_ERROR, {method: 'login', errmsg: e.message});
	    			softphone.InternalOnError(err.message, err.code, err.name);
	    			softphone.OnLinkDisconnected();
					return false;
				}
		    }

		    softphone.agentlogout = function()
		    {
		    	try{
					var params = {};
					params.type = 1;
					softphone.callexecuteAction('doLogout',  params);
					return true;
				}catch(e) {
					this.logmsg("agentlogout error:"+e.message);
					return false;
				}
		    }
		    
		    softphone.agentnotready = function(workmode)
		    {
		    	if (workmode == 4) {
		    		return softphone.acw();
		    	}
		    	softphone.aux(0);
		    }
		    
		    softphone.aux = function(reasoncode)
		    {
		    	try{
					var desc=TRCCLinkConfig.reasoncodes[reasoncode];
					if(typeof(desc)=="undefined"){
						desc=TRCCLinkConfig.reasoncodes[0];
					}
					var params={};
					params.description=desc;
					softphone.callexecuteAction('doPause',params);
					return true;
				}catch(e){
					this.logmsg("aux error:"+e.message);
					return false;
				}
		    }
		    softphone.acw = function()
		    {
		    	this.logmsg("acw is not supported");
				return false;
		    }
		    softphone.agentready = function(workmode)
		    {
		    	try{
					softphone.callexecuteAction('doUnpause');
				} catch(e) {
					this.logmsg("ready error:"+e.message);
					return false;
				}	
		   	}
		    softphone.makecall = function(dest,ani)
		    {
		    	try{
					var params = {};
					params.tel = dest;
					params.callType = '3'; //3点击外呼
					if(ani!=""){
						params.obClidLeftNumber=ani;
					}
					//this.logmsg("executeAction doPreviewOutCall,params:"+JSON.stringify(params));
					softphone.callexecuteAction("doPreviewOutCall", params);
					return true;
				}catch(e){
					this.logmsg("ready error:"+e.message);
					return false;
				}
		    }
		    softphone.doUnlink=function()
			{
				try{
					softphone.callexecuteAction("doUnLink");
					return true;
				}catch(e){
					this.logmsg("doUnlink error:"+e.message);
					return false;
				}
			}
			
			softphone.doPreviewOBCancel=function()
			{
				try{
					softphone.callexecuteAction("doPreviewOutcallCancel");
					return true;
				}catch(e){
					this.logmsg("doPreviewOBCancel error:"+e.message);
					return false;
				}
			}
		    
		    softphone.releasecall = function()
		    {
		    	if(this.previewobcancel){
		    		return this.doPreviewOBCancel();
		    	}
		    	return this.doUnlink();
		    }

		    softphone.holdcall = function()
		    {
		    	try {
		    		softphone.callexecuteAction("doHold");
					return true;
				}catch(e){
					this.logmsg("doHold error:"+e.message);
					return false;
				}
		    }
		    softphone.answercall=function()
		    {
		    	try {
		    		softphone.callexecuteAction("doLink");
					return true;
				}catch(e){
					this.logmsg("doLink error:"+e.message);
					return false;
				}
		    }
		    softphone.retrievecall=function(callid)
		    {
		    	try{
		    		softphone.callexecuteAction("doUnhold");
					return true;
				}catch(e){
					this.logmsg("doUnhold error:"+e.message);
					return false;
				}
		    }
			
			softphone.inittransfer = function(callid, dest, userdatas)
			{
				try{
					//no attach data interface,just ignore datas
					//this.logmsg("executeAction doConsultTransfer");
					var type = "0";
			        if (TRCCLinkConfig.agentidrangeregex.test(dest))
			        {
			            type = "1";
			        }else if (TRCCLinkConfig.extensionrangeregex.test(dest))
			        {
			            type = "2";
			        }
					params={};
					params.consultObject=dest;
					params.objectType=type;
					softphone.callexecuteAction("doConsult",params);
					this.currentdest=dest;
					return true;
				}catch(e){
					this.logmsg("inittransfer error:"+e.message);
					return false;
				}
			}
			softphone.initconference = function(callid, dest, userdatas)
			{
				try{
					this.logmsg("initconference just like inittransfer");
					
					return softphone.inittransfer(callid, dest, userdatas);
				}catch(e){
					this.logmsg("initconference error:"+e.message);
					return false;
				}
			}
		    
		    softphone.reconnect=function()
			{
				try{
					softphone.callexecuteAction("doConsultCancel");
					return true;
				}catch(e){
					this.logmsg("doConsultCancel error:"+e.message);
					return false;
				}
			}
			softphone.completetransfer=function()
			{
				try{
					//this.logmsg("executeAction doConsultTransfer");
					var params={};
					softphone.callexecuteAction("doConsultTransfer",params);
					return true;
				}catch(e){
					this.logmsg("completetransfer error:"+e.message);
					return false;
				}
			}
			softphone.completeconference=function()
			{
				try{
					//this.logmsg("executeAction doConsultThreeway");
					var params={};
					softphone.callexecuteAction("doConsultThreeway",params);
					return true;
				}catch(e){
					this.logmsg("completeconference error:"+e.message);
					return false;
				}
			}
			softphone.mutetransfer=function(callid, dest, userdatas)
			{
				try{
					if(dest=='investigation'){
						softphone.callexecuteAction("doInvestigation");
						return true;
					}
					var type = "0";
			        if (TRCCLinkConfig.agentidrangeregex.test(dest))
			        {
			            //agent
			            type = "1";
			        }else if (dest.startsWith("ivr"))
			        {
			            //ivr
			            type = "3";
			            dest = dest.substr(3);
			        }
					params={};
					params.transferObject = dest;
					params.objectType = type;
					softphone.callexecuteAction("doTransfer",params);
					return true;
				}catch(e){
					this.logmsg("mutetransfer error:"+e.message);
					return false;
				}
			}
			
			softphone.senddtmf = function(dtmf)
			{
				//no interface
				return false;
			}
			softphone.listen = function(agentid)
			{
				try{
					var params={};
					params.spyObject = this.dn;
					params.objectType = '1';
					params.spiedCno = agentid;
					softphone.callexecuteAction('doSpy', params);
					this.inspy=true;
				}catch(e){
					this.logmsg("listen error:"+e.message);
					return false;
				}
			}

			//On xxx
			softphone.OnCTIEvent = function(evt) {
				this.logmsg("[OnCTIEvent]:" + JSON.stringify(evt));
				this.OnMessage(evt);
			}

			softphone.OnLinkDisconnected = function()
			{
				this.logined = false;
				var ret = {};
				addJsonIntValue(ret,"event", MSGTYPE.EVT_LINKDISCONNCTED);
				addJsonStringValue(ret,"eventdesc","EVT_LINKDISCONNCTED");
				this.OnCTIEvent(ret);
			}
			softphone.OnAgentLogin = function()
			{
				if(!this.logined){
					this.logined = true;
					var ret = {};
			    	addJsonIntValue(ret,"event", MSGTYPE.EVT_AGENTLOGIN);
			    	addJsonIntValue(ret,"workmode", 3);
			    	addJsonStringValue(ret,"dn", this.dn);
			    	addJsonIntValue(ret,"channelid", this.channelid);
			    	addJsonStringValue(ret,"eventdesc","EVT_AGENTLOGIN");
			    	this.OnCTIEvent(ret);
			    }
			}
			softphone.OnAgentNotReady = function()
			{
				this.logined = true;
				var ret = {};
				addJsonIntValue(ret,"event", MSGTYPE.EVT_AGENTNOTREADY);
				addJsonIntValue(ret,"workmode", 3);
				addJsonStringValue(ret,"dn", this.dn);
				addJsonIntValue(ret,"channelid", this.channelid); 
				addJsonStringValue(ret,"eventdesc","EVT_AGENTNOTREADY");
				this.OnCTIEvent(ret);
			}
			
			softphone.OnAgentReady = function()
			{
				this.logined = true;
				var ret={};
				addJsonIntValue(ret,"event", MSGTYPE.EVT_AGENTREADY);
				addJsonIntValue(ret,"workmode", 2);
				addJsonStringValue(ret,"dn", this.dn);
				addJsonIntValue(ret,"channelid", this.channelid);
				addJsonStringValue(ret,"eventdesc","EVT_AGENTREADY");
				this.OnCTIEvent(ret);
			}
			softphone.OnAgentLogout = function()
			{
				this.logined = false;
				var ret = {};
				addJsonIntValue(ret,"event", MSGTYPE.EVT_AGENTLOGOUT);
				addJsonIntValue(ret,"workmode", 0);
				addJsonStringValue(ret,"dn", this.dn);
			    addJsonIntValue(ret,"channelid", this.channelid);
			    addJsonStringValue(ret,"eventdesc","EVT_AGENTLOGOUT");
			    this.OnCTIEvent(ret);
			}
			
			//Thisstatus
			softphone.OnOutRingingEvent = function(evt)
		    {
		        if (evt.name == "ringing")
		        {
		            this.islink = false;
		        }
		    }
			
			softphone.OnAllCallReleased = function()
			{
		    	//release all call id here
		    	this.islink=false;
		    	this.previewobcancel=false;
		    	if(this.activeid != "")
		    	{
		    		var evt = {};
		    		addJsonIntValue(evt,"event",MSGTYPE.EVT_RELEASED);
		    		addJsonStringValue(evt,"eventdesc","EVT_RELEASED");
		    		addJsonStringValue(evt,"dn",this.dn);
		    		addJsonStringValue(evt,"channelid",this.channelid);
		    		addJsonStringValue(evt,"callid",this.activeid);
		    		this.activeid = "";
		    		this.OnCTIEvent(evt);
		    	}
		    	if(this.heldid!="")
		    	{
		    		var evt={};
		    		addJsonIntValue(evt,"event",MSGTYPE.EVT_RELEASED);
		    		addJsonStringValue(evt,"eventdesc","EVT_RELEASED");
		    		addJsonStringValue(evt,"dn",this.dn);
		    		addJsonStringValue(evt,"channelid",this.channelid);
		    		addJsonStringValue(evt,"callid",this.heldid);
		    		this.heldid = "";
		    		this.OnCTIEvent(evt);
		    	}
		    }
			softphone.OnPauseEvent = function(jsonObj)
		    {
	
		        if (!this.logined)
		        {
		            this.logined = true;
		            var evt = {};
		            addJsonIntValue(evt,"event", MSGTYPE.EVT_AGENTLOGIN);
		            addJsonStringValue(evt,"dn", this.dn);
		            addJsonStringValue(evt,"agentid", this.agentid);
		            addJsonStringValue(evt,"eventdesc","EVT_AGENTLOGIN");
		            this.OnCTIEvent(evt);
		        }
		        var loginStatus = getJsonString(jsonObj, "loginStatus");
		        if (loginStatus != "")
		        {
		            if (loginStatus == "online")
		            {
		                var evt = {};
		                addJsonIntValue(evt,"event", MSGTYPE.EVT_AGENTREADY);
		                addJsonIntValue(evt,"workmode", 2);
		                addJsonStringValue(evt,"dn", this.dn);
		                addJsonStringValue(evt,"agentid", this.agentid);
		                addJsonStringValue(evt,"eventdesc","EVT_AGENTREADY");
		                this.OnCTIEvent(evt);
		            } else if (loginStatus == "pause")
		            {
		                if (jsonObj.deviceStatus=="idle")
		                {
		                    var desc = getJsonString(jsonObj, "pauseDescription");
		                    if (desc!="pauseOutCalling")
		                    {
		                        this.OnAllCallReleased();
		                    }
		                }
		                var evt = {};
		                addJsonIntValue(evt,"event", MSGTYPE.EVT_AGENTNOTREADY);
		                addJsonIntValue(evt,"workMode", 3);
		                addJsonStringValue(evt,"dn", this.dn);
		                addJsonStringValue(evt,"agentid", this.agentid);
		                var desc = getJsonString(jsonObj,"pauseDescription");
		                if (desc != "")
		                {
		                    var reasoncode = 0;
		                   	var i=0;
		                   	for(i=0; i<10; i++){
		                   		if(TRCCLinkConfig.reasoncodes[i] == desc){
		                   			reasoncode = i;
		                   			break;
		                   		}
		                   	}
		                   	addJsonIntValue(evt, "reasoncode", reasoncode);
		                }
		                addJsonStringValue(evt,"eventdesc","EVT_AGENTNOTREADY");
		                this.OnCTIEvent(evt);
		            }
		        }
		    }
			softphone.OnOnlineEvent = function(jsonObj)
		    {
		        if (!this.logined)
		        {
		            this.logined = true;
		            var evt = {};
		            addJsonIntValue(evt,"event", MSGTYPE.EVT_AGENTLOGIN);
		            addJsonStringValue(evt,"dn", this.dn);
		            addJsonStringValue(evt,"agentid", this.agentid);
		            this.OnCTIEvent(evt);
		        }
		        if (jsonObj.deviceStatus == "idle")
		        {
		            this.OnAllCallReleased();
		        }
		        var loginStatus = getJsonString(jsonObj,"loginStatus");
		        if (loginStatus != '')
		        {
		            if (loginStatus=="online")
		            {
		                var evt = {};
		                addJsonIntValue(evt,"event", MSGTYPE.EVT_AGENTREADY);
		                addJsonIntValue(evt,"workmode", 2);
		                addJsonStringValue(evt,"dn", this.dn);
		                addJsonStringValue(evt,"agentid", this.agentid);
		                addJsonStringValue(evt,"eventdesc","EVT_AGENTREADY");
		                this.OnCTIEvent(evt);
		            }
		            else if (loginStatus == "pause")
		            {
		                var evt = {};
		                addJsonIntValue(evt,"event", MSGTYPE.EVT_AGENTNOTREADY);
		                addJsonStringValue(evt,"eventdesc","EVT_AGENTNOTREADY");
		                addJsonIntValue(evt,"workmode", 3);
		                addJsonStringValue(evt,"dn", this.dn);
		                addJsonStringValue(evt,"agentid", this.agentid);
		                this.OnCTIEvent(evt);
		            }
		        }
		    }
			softphone.OnDialing = function(jsonObj)
			{
				var evt = {};
				addJsonIntValue(evt,"event", MSGTYPE.EVT_DIALING);
				addJsonStringValue(evt,"dn", this.dn);
				addJsonIntValue(evt,"channelID", this.channelid);
				if (this.heldid==conn1)
				{
					this.activeid = conn2;
				} else  {
					this.activeid = conn1;
				}
				addJsonIntValue(evt,"callid", this.activeid);
				addJsonStringValue(evt,"eventdesc","EVT_DIALING");
				this.OnCTIEvent(evt);
			}
			softphone.OnOutBusyEvent = function(jsonObj)
		    {
		        this.islink=true;
		        var ANI =getJsonString(jsonObj,"numberTrunk");
		        var DNIS = getJsonString(jsonObj,"customerNumber");
		        var OtherDN = DNIS;
		        var evt = {};
		        addJsonIntValue(evt,"event", MSGTYPE.EVT_ESTABLISH);
		        addJsonStringValue(evt,"eventdesc","EVT_ESTABLISH");
		        addJsonStringValue(evt,"dn", this.dn);
		        addJsonStringValue(evt,"otherdn", OtherDN);
		        addJsonStringValue(evt,"callid", this.activeid);
	
		        var UCID = getJsonString(jsonObj,"uniqueId");
		        var calltype =getJsonString(jsonObj,"callType");
		        if (UCID!="")
		        {
		            var datas = {};
		            addJsonStringValue(datas,"ucid", calltype + "%7c" + UCID);
		            addJsonDatasValue(evt,"userdata",datas);
		            addJsonStringValue(evt,"ucid", calltype + "%7c" + UCID);
		        }
		        this.OnCTIEvent(evt);
		    }
			softphone.OnPauseUnlinkEvent=function(jsonObj)
		    {
		        this.OnAllCallReleased();
		        var evt2 = {};
		        addJsonIntValue(evt2,"event", MSGTYPE.EVT_AGENTNOTREADY);
		        addJsonStringValue(evt2,"eventdesc", "EVT_AGENTNOTREADY");
		        addJsonIntValue(evt2,"workmode", 3);
		        addJsonStringValue(evt2,"dn", this.dn);
		        addJsonStringValue(evt2,"agentid", this.agentid);
		        addJsonIntValue(evt2,"reasoncode",0);
		        this.OnCTIEvent(evt2);
		    }
	    
		    softphone.OnHoldEvent = function (jsonObj)
		    {
		        this.heldid = this.activeid;
		        this.activeid = "";
		        var evt = {};
		        addJsonIntValue(evt,"event", MSGTYPE.EVT_HELD);
		        addJsonStringValue(evt,"eventdesc","EVT_HELD");
		        addJsonStringValue(evt,"dn", this.dn);
		        addJsonStringValue(evt,"callid", this.heldid);
		        addJsonStringValue(evt,"holdingdevice", this.dn);
		        this.OnCTIEvent(evt);
		    }
	    
		    softphone.OnUnholdEvent  =function(jsonObj)
		    {
		        this.activeid = this.heldid;
		        this.heldid = "";
		        var evt = {};
		        addJsonIntValue(evt,"event", MSGTYPE.EVT_RETRIEVED);
		        addJsonStringValue(evt,"eventdesc","EVT_RETRIEVED");
		        addJsonStringValue(evt,"dn", this.dn);
		        addJsonStringValue(evt,"callid", this.activeid);
		        this.OnCTIEvent(evt);
		    }
	    
		    softphone.OnWaitLinkEvent = function(jsonObj)
		    {
		        var evt = {};
		        addJsonIntValue(evt,"event", MSGTYPE.EVT_RINGBACK);
		        addJsonStringValue(evt,"eventdesc","EVT_RINGBACK");
		        addJsonStringValue(evt,"dn", this.dn);
		        addJsonStringValue(evt,"callid", this.activeid);
		        this.OnCTIEvent(evt);
		    }
	    
		    softphone.OnComRingingEvent = function(jsonObj)
		    {
		        this.islink = true;
		        this.activeid = conn1;
		        this.heldid = "";
		        var ANI = getJsonString(jsonObj,"customerNumber");
		        var DNIS = getJsonString(jsonObj,"numberTrunk");
		        var UCID = getJsonString(jsonObj,"uniqueId");
		        var calltype =getJsonString(jsonObj,"callType");
		        var IVRFlow = getJsonString(jsonObj,"cdr_ivr_flow");
		        var evt = {};
		        addJsonIntValue(evt,"event", MSGTYPE.EVT_RINGING);
		        addJsonStringValue(evt,"dn", this.dn);
		        addJsonStringValue(evt,"callid", this.activeid);
		        addJsonStringValue(evt,"ani", ANI);
		        addJsonStringValue(evt,"dnis", DNIS);
		        if (UCID!="")
		        {
		            var datas = {};
		            addJsonStringValue(datas,"ucid", calltype + "%7c" + UCID);
		            if (IVRFlow!="")
		            {
		                addJsonStringValue(datas,"cdr_ivr_flow", IVRFlow);
		            }
		            addJsonDatasValue(evt,"userdata", datas);
		            addJsonStringValue(evt,"ucid", calltype + "%7c" + UCID);
	
		        }
		        this.OnCTIEvent(evt);
		    }
	    
		    softphone.OnNormalBusyEvent = function(jsonObj)
		    {
		        this.islink = true;
		        var ANI =getJsonString(jsonObj,"numberTrunk");
		        var DNIS = getJsonString(jsonObj,"customerNumber");
		        var OtherDN = DNIS;
		        var Name = getJsonString(jsonObj,"name");
		        if (Name == "unconsult")
		        {
		            var evt = {};
		            addJsonIntValue(evt,"event", MSGTYPE.EVT_RELEASED);
		            addJsonStringValue(evt,"dn", this.dn);
		            addJsonStringValue(evt,"callid", this.activeid);
		            this.OnCTIEvent(evt);
		            var evt2 = {};
		            addJsonIntValue(evt2,"event", MSGTYPE.EVT_RETRIEVED);
		            addJsonStringValue(evt2,"dn", this.dn);
		            addJsonStringValue(evt2,"callid", this.heldid);
		            this.OnCTIEvent(evt2);
		            this.activeid = this.heldid;
		            this.heldid = "";
		        }
		        else if (Name == "consultThreewayUnlink")
		        {
		            var evt = {};
		            addJsonIntValue(evt,"event", MSGTYPE.EVT_PARTYDELETED);
		            addJsonStringValue(evt,"thisdn", this.dn);
		            addJsonStringValue(evt,"callid", this.activeid);
		            addJsonStringValue(evt,"thirdpartydn", this.currentdest);
		            this.OnCTIEvent(evt);
		        }
		        else if (Name == "consultError")
		        {
		        	this.InternalOnErrorCode(jsonObj.code, jsonObj.msg);
		        } else {
		            var evt = {};
		            addJsonIntValue(evt,"event", MSGTYPE.EVT_ESTABLISH);
		            addJsonStringValue(evt,"dn", this.dn);
		            addJsonStringValue(evt,"otherdn", OtherDN);
		            addJsonStringValue(evt,"callid", this.activeid);
	
		            var UCID = getJsonString(jsonObj,"uniqueId");
		            var calltype = getJsonString(jsonObj,"callType");
	
		            if (UCID!="")
		            {
		                var datas = {};
		                //datas.AddData("UCID", calltype + "|" + UCID);
		                addJsonStringValue(datas,"ucid", calltype + "%7c" + UCID);
		                addJsonDatasValue(evt,"userdata", datas);
		                addJsonStringValue(evt,"ucid", calltype + "%7c" + UCID);
		            }
		            this.OnCTIEvent(evt);
		        }
		    }
	    
		    softphone.OnNeatenStartEvent = function(jsonObj)
		    {
		        if (getJsonString(jsonObj,"deviceStatus")=="idle")
		        {
		            this.OnAllCallReleased();
		        }
		        var evt = {};
		        addJsonIntValue(evt,"event", MSGTYPE.EVT_AGENTNOTREADY);
		        addJsonIntValue(evt,"workmode", 4);
		        addJsonStringValue(evt,"dn", this.dn);
		        addJsonStringValue(evt,"agentid", this.agentid);
		        this.OnCTIEvent(evt);
		    }
	    
		    softphone.OnNeatenEndEvent=function(jsonObj)
		    {
		        if (getJsonString(jsonObj,"deviceStatus")=="idle")
		        {
		            this.OnAllCallReleased();
		        }
		        var evt = {};
		        if (getJsonString(jsonObj,"loginStatus")=="online")
		        {
		            addJsonIntValue(evt,"event", MSGTYPE.EVT_AGENTREADY);
		            addJsonIntValue(evt,"workmode", 2);
		        }
		        else
		        {
		            addJsonIntValue(evt,"event", MSGTYPE.EVT_AGENTNOTREADY);
		            addJsonIntValue(evt,"workmode", 3);
		        }
		        addJsonStringValue(evt,"dn", this.dn);
		        addJsonStringValue(evt,"agentid", this.agentid);
		        this.OnCTIEvent(evt);
		    }

		    softphone.OnOnlineUnlinkEvent = function(jsonObj)
		    {
		        this.OnAllCallReleased();
		        var evt = {};
		        addJsonIntValue(evt,"event", MSGTYPE.EVT_AGENTREADY);
		        addJsonIntValue(evt,"workmode", 2);
		        addJsonStringValue(evt,"dn", this.dn);
		        addJsonStringValue(evt,"agentid", this.agentid);
		        this.OnCTIEvent(evt);
		    }    
	    
		    softphone.OnConsultLinkEvent = function(jsonObj)
		    {
		        this.islink = true;
		        var evt = {};
		        addJsonIntValue(evt,"event", MSGTYPE.EVT_ESTABLISH);
		        addJsonStringValue(evt,"dn", this.dn);
		        addJsonStringValue(evt,"callid", this.activeid);
		        this.OnCTIEvent(evt);
		    }
	    
		    softphone.OnConsultOrTransferBusyEvent = function(jsonObj)
		    {
		        this.islink = true;//挂机需要
		        addJsonIntValue(evt,"event", MSGTYPE.EVT_ESTABLISH);
		        addJsonStringValue(evt,"dn", this.dn);
		        addJsonStringValue(evt,"callid", this.activeid);
		        this.OnCTIEvent(evt);
		    }
	  
		    softphone.OnResponseEvent = function(jsonObj)
		    {
		    	if (jsonObj.code == '0') {
			    	if (jsonObj.reqType == 'consult') {
				        this.heldid = this.activeid;
				        if (this.activeid == conn1) {
				        	this.activeid = conn2;
				        } else {
				        	this.activeid = conn1;
				        };
				        var evt = {};
				        addJsonIntValue(evt,"event", MSGTYPE.EVT_HELD);
				        addJsonStringValue(evt,"eventdesc","EVT_HELD");
				        addJsonStringValue(evt,"dn", this.dn);
				        addJsonStringValue(evt,"callid", this.heldid);
				        addJsonStringValue(evt,"holdingdevice", this.dn);
				        this.OnCTIEvent(evt);
			    		evt = {};
			    		addJsonIntValue(evt, "event", MSGTYPE.EVT_DIALING);
			    		addJsonStringValue(evt, "eventdesc", "EVT_DIALING");
			    		addJsonStringValue(evt, "dn", this.dn);
			    		addJsonStringValue(evt, "callid", this.activeid);
			    		addJsonStringValue(evt, "prevconnectionid", this.heldid);
			    		this.OnCTIEvent(evt);
			    	}
			    	if (jsonObj.reqType == 'consultThreeway')
			    	{
			    		var evt = {};
			    		addJsonIntValue(evt, "event", MSGTYPE.EVT_CONFERENCED);
			    		addJsonStringValue(evt, "dn", this.dn);
			    		addJsonStringValue(evt, "callid", this.activeid);
			    		addJsonStringValue(evt, "heldcallid", this.heldid);
			    		addJsonStringValue(evt, "prevconnectionid", this.heldid);
			    		this.OnCTIEvent(evt);
			    		this.heldid = "";
			    	}
 		    	} else {
 		    		softphone.InternalOnErrorCode(jsonObj.code, jsonObj.msg);
 		    	}
		    }
			
			//cb xxx
			softphone.CommonCallBack = function(funcname, token)
			{
				softphone.logmsg(funcname, token);
				if(token.code == "0"){
					softphone.logmsg(funcname + "成功");
				}else{
					softphone.logmsg(functiona,e+"失败:" + token.msg);
					softphone.InternalOnErrorCode(token.code, token.msg);
				}
			}

			softphone.callexecuteAction = function(action, params) {
				if (params) {
					softphone.logmsg('Action: ' + action, params)
					executeAction(action, params);
				} else {
					softphone.logmsg('Action: ' + action)
					executeAction(action);
				}
			}
			
			softphone.cbLogin = function(token)
			{
				softphone.logmsg("cbLogin", token);
				if(token.code == "0") {
					softphone.logmsg("login success");
					softphone.OnAgentLogin();
				} else {
					softphone.logmsg("login fail！" + token.msg);
					softphone.InternalOnErrorCode(token.code, token.msg);
					softphone.OnLinkDisconnected();
				}
			}

			softphone.cbLogout = function(token)
			{//退出
				softphone.logmsg("cbLogout", token);
				if(token.code == "0"){
					softphone.logmsg("login success");
					softphone.OnAgentLogout();
					softphone.OnLinkDisconnected();
				} else {
					softphone.logmsg("logout fail！" + token.msg);
					softphone.InternalOnErrorCode(token.code,token.msg);
				}	
			}

			/**
			 * 外呼回调 cbPreviewOutCall
			 * 返回json对象token:  "type":"response","code":"0","msg":"ok","reqType":"previewOutCall" 
			 * code描述
			0  ：成功
			6  ：外呼失败，参数错误
			13 ：外呼失败，外呼号码格式错误
			20 ：外呼失败，呼叫范围受限
			25 ：外呼失败，此号码为黑名单
			26 ：外呼失败，座席没有外呼权限，请联系管理员
			27 ：外呼失败，余额不足
			28 ：外呼失败，没有路由  
			*/
			softphone.cbPreviewOutCall = function(token)
			{  //外呼回调
				softphone.logmsg("cbPreviewOutCall", token);
				if(token.code == "0"){
					softphone.logmsg("PreviewOutCall发起成功");
					softphone.previewobcancel = true;
					softphone.OnDialing(token);
				} else {
					softphone.logmsg("cbPreviewOutCall发起失败！" + token.msg);
					softphone.InternalOnErrorCode(token.code,token.msg);
				}
			}

			softphone.cbPreviewOutCallCancel = function(token)
			{
				softphone.CommonCallBack("cbPreviewOutCallCancel", token);
			}

			softphone.cbTransfer = function(token)
			{
				softphone.CommonCallBack("cbTransfer",token);
			}

			softphone.cbConsultCancel = function(token)
			{
				softphone.CommonCallBack("cbConsultCancel", token);
			}

			softphone.cbUnconsult = function(token)
			{
				softphone.CommonCallBack("cbUnconsult", token);
			}

			softphone.cbConsultTransfer = function(token)
			{
				softphone.CommonCallBack("cbConsultTransfer", token);
			}
			
			//softphone.cbOrderCallBack = function(token)
			//{
			//	softphone.CommonCallBack("cbOrderCallBack", token);
			//}
			
			softphone.cbPause = function(token)
			{
				softphone.CommonCallBack("cbPause",token);
			}
			
			softphone.cbUnpause = function(token)
			{
				softphone.logmsg("cbUnPause", token);
				if(token.code == "0"){
					softphone.logmsg("ready success");
					softphone.OnAgentReady();
				} else {
					softphone.logmsg("pause fail！" + token.msg);
					softphone.InternalOnErrorCode(token.code, token.msg);
				}
			}

		    softphone.cbThisStatus = function(token)
		    {
		    	softphone.logmsg("cbThisStatus", token);
		    	var type = getJsonString(token, "type");
		    	if (type == "event")
		    	{
		    		softphone.logmsg("begin handle event " + token.eventName);
		    		switch (token.eventName)
		    		{
		    		case "outRinging":
		    			softphone.OnOutRingingEvent(token);
		    			break;
		    		case "comeRinging":
		    			softphone.OnComRingingEvent(token);
		    			break;
		    		case "normalBusy":
		    			softphone.OnNormalBusyEvent(token);
		    			break;
		    		case "outBusy":
		    			softphone.OnOutBusyEvent(token);
		    			break;
		    		case "online":
		    			softphone.OnOnlineEvent(token);
		    			break;
		    		case "pause":
		    			softphone.OnPauseEvent(token);
		    			break;
		    		case "waitLink":
		    			softphone.OnWaitLinkEvent(token);
		    			break;
		    		case "neatenStart":
		    			//MessageBox.Show("座席整理状态开始");
		    			softphone.OnNeatenStartEvent(token);
		    			break;
		    		case "neatenEnd":
		    			//MessageBox.Show("座席整理状态结束");
		    			softphone.OnNeatenEndEvent(token);
		    			break;
		            case "hold":
		            	softphone.OnHoldEvent(token);
		            	break;
		            case "unHold":
		                softphone.OnUnholdEvent(token);
		                break;
		            case "onlineUnlink":
		                softphone.OnOnlineUnlinkEvent(token);
		                break;
		            case "pauseUnlink":
		                softphone.OnPauseUnlinkEvent(token);
		                break;
		            case "consultLink":
		                softphone.OnConsultLinkEvent(token);
		                break;
		            case "consulterOrTransferBusy":
		                softphone.OnConsultOrTransferBusyEvent(token);
		                break;
		            default:
		             	softphone.logmsg("unhandled message:"+token.eventName);
		             	break;
		          	}
		          	softphone.logmsg("after event " + token["eventName"] + ",active id:" + softphone.activeid + ",m_HeldID:" + softphone.heldid);
		    	} else if (type=="response")
		    	{
		    		softphone.OnResponseEvent(token);
		    	}
		    }

		    return softphone;
		}
	};
	
	return ELITETRCCLINK.createNew();
});
